﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace HomeWork
{
    /*    编写一个程序，以实现机器人的层次结构，此层次结构将至少包含抽象类机器人类Robot、
     *    炒菜机器人类CookRobot、传菜机器人类DeliveryRobot。
    Robot类应包含机器人姓名name字段、机器人工作的方法Working()，该方法应该在子类中被实现，
    机器人工作的方式很多，所以Working()方法应该被定义为抽象方法。

    可以在CookRobot中添加一个代表菜的类型的字段，用枚举类型；在DeliveryRobot中添加一个代表连续工作时长的字段hours。
    CookRobot和DeliveryRobot应实现具体的Working()方法。

    在主类中定义一个方法，形参数据类型是string，返回值数据类型是Robot，方法中实现如果传入的字符串是“炒菜”，
    那就返回CookRobot的实例（当然是要用Robot的引用指向的），如果传入的字符串是“传菜”，
    那就返回DeliveryRobot的实例。

    Main方法中：用户输入所选择的机器人的功能，根据用户的输入Robot执行对应的功能。*/

    enum DishType
    {
        番茄炒蛋,
        红烧茄子,
        糖醋排骨,
        扬州炒饭
    }
    class Program2
    {
        static void Main(string[] args)
        {
            DeliveryRobot d = new DeliveryRobot("MyDeliveryRobot");
            while (true)
            {
                Console.WriteLine("请输入机器人类型(炒菜或传菜):");
                string s = Console.ReadLine();
                while (true)
                {
                    if (s != "炒菜" && s != "传菜")
                    {
                        Console.WriteLine("请重新输入");
                        s = Console.ReadLine();
                        continue;
                    }
                    break;
                }
                Robot robot = ReturnRobots(s);
                if (robot is CookRobot)
                {
                    int choice;
                    Console.WriteLine("菜单：1.番茄炒蛋, 2.红烧茄子, 3.糖醋排骨, 4.扬州炒饭");
                    Console.WriteLine("请输入你想要的菜品：");
                    while (true)
                    {
                        try
                        {
                            choice = int.Parse(Console.ReadLine());
                            if (choice < 1 || choice > 4)
                            {
                                Console.WriteLine("请重新输入");
                                continue;
                            }
                            break;
                        }
                        catch (Exception)
                        {
                            Console.WriteLine("请重新输入");
                        }
                    }
                    CookRobot c = robot as CookRobot;
                    c.Cooked += d.TakeDish;
                    c.Dish = (DishType)choice - 1;
                    c.Working();
                }
                else
                {
                    Console.WriteLine("请先点菜");
                }
            }
        }

        static Robot ReturnRobots(string s)
        {
            Robot r = null;
            switch (s)
            {
                case "炒菜":
                    r = new CookRobot("CookRobot");
                    break;
                case "传菜":
                    r = new DeliveryRobot("MyDeliveryRobot");
                    break;
                default:
                    break;
            }
            return r;
        }
    }
    abstract class Robot
    {
        private string _name;

        public string Name { get => _name; set => _name = value; }

        protected Robot(string name)
        {
            _name = name;
        }
        public Robot()
        {

        }

        public abstract void Working();

    }

    class CookedEventArgs : EventArgs
    {
        public DishType dish;
    }

    class CookRobot : Robot
    {
        private DishType dish;

        private EventHandler eventHandler;

        public event EventHandler Cooked
        {
            add
            {
                eventHandler += value;
            }
            remove
            {
                eventHandler -= value;
            }
        }
        public DishType Dish { get => dish; set => dish = value; }

        public CookRobot(DishType dish, string name) : base(name)
        {
            this.dish = dish;
        }
        public CookRobot(string name) : base(name)
        {

        }

        public override void Working()
        {
            Console.WriteLine($"my name is {this.Name},i will cook {dish.ToString()}");
            for (int i = 0; i < 5; i++)
            {
                Thread.Sleep(1000);
                Console.WriteLine($"{i + 1}s later...");
            }
            Console.WriteLine("i have done the job,call waiter");
            OnCooked();
        }

        public void OnCooked()
        {
            CookedEventArgs args = new CookedEventArgs();
            args.dish = this.dish;
            if (eventHandler != null)
            {
                eventHandler.Invoke(this,args);
            }
        }
    }

    class DeliveryRobot : Robot
    {
        private double hours;

        public double Hours { get => hours; set => hours = value; }

        public DeliveryRobot(double hours, string name) : base(name)
        {
            this.hours = hours;
        }

        public DeliveryRobot(string name) : base(name)
        {

        }

        public void TakeDish(object o, EventArgs e)
        { 
            CookedEventArgs c = e as CookedEventArgs;
            hours += 1;
            Console.WriteLine($"my name is {this.Name},i am taking your dishs{c.dish.ToString()}");
            Working();
            
        }
        public override void Working()
        {
            Console.WriteLine($"my name is {this.Name},i have worked {this.hours}hours");
        }
    }
}
